#include "CudaEpiModel.h"
#include "CudaEpiModel.h"
#include "CudaParam.h"
#include <thrust/copy.h>
#include <thrust/sort.h>
#include <thrust/remove.h>
#include <thrust/count.h>
#include <thrust/sort.h>
#include <thrust/binary_search.h>

void cudaTravelEnd(){
	thrust::for_each(comm_visitor_vec->begin(),comm_visitor_vec->end(),
		TravelEndOp(thrust::raw_pointer_cast(ppl_vec->data()),
					thrust::raw_pointer_cast(comm_vec->data())));

	int size = comm_visitor_vec->size();
	size -= thrust::count_if(comm_visitor_vec->begin(),comm_visitor_vec->end(),TravelRemoveOp());
	thrust::remove_if(comm_visitor_vec->begin(),comm_visitor_vec->end(),TravelRemoveOp());
	comm_visitor_vec->resize(size);
}

void cudaTravelStart(){
	thrust::device_vector<dCommVisitor> new_visitor_vec(model->nNumPerson);

	thrust::for_each(ppl_vec->begin(),ppl_vec->end(),
		TravelStartOp(thrust::raw_pointer_cast(ppl_vec->data()),
					  thrust::raw_pointer_cast(tract_vec->data()),
					  thrust::raw_pointer_cast(comm_vec->data()),
					  thrust::raw_pointer_cast(rand_vec->data()),
					  thrust::raw_pointer_cast(new_visitor_vec.data()),
					  model->nNumTractsTotal));
	
	int size = thrust::count_if(new_visitor_vec.begin(),new_visitor_vec.end(),TravelRemoveOp());
	size = model->nNumPerson - size;
	thrust::remove_if(new_visitor_vec.begin(),new_visitor_vec.end(),TravelRemoveOp());
	new_visitor_vec.resize(size);
	
	int comm_visitor_size = comm_visitor_vec->size();
	int new_comm_visitor_size = comm_visitor_size + size;
	comm_visitor_vec->resize(new_comm_visitor_size);
	
	thrust::copy(new_visitor_vec.begin(),new_visitor_vec.end(),comm_visitor_vec->begin()+comm_visitor_size);
	
	thrust::sort(comm_visitor_vec->begin(),comm_visitor_vec->end());
	
	thrust::lower_bound(
		comm_visitor_vec->begin(),comm_visitor_vec->end(),
		comm_visitor_counter->begin(),comm_visitor_counter->end(),
		comm_visitor_start_vec->begin());

	thrust::upper_bound(
		comm_visitor_vec->begin(),comm_visitor_vec->end(),
		comm_visitor_counter->begin(),comm_visitor_counter->end(),
		comm_visitor_end_vec->begin());
}